<script setup lang="ts">
// 基础数据类型
// 布尔值
let isDone: boolean = false
console.log('isDone',isDone);

// 字符串
let firstname: string = "xiaoming"
console.log("firstname: ", firstname)

// 数字
let age: number = 20
console.log("age: ", age)
let str: string = `hello ${firstname}, ${age}`
console.log("str: ", str)

// 是所有数据类型的子类型
// let n: null = null
// let u: undefined = undefined

// let num: number = u
// console.log("num: ", num)
// let num2: number = n
// console.log("num2: ", num2)

// 数组
let strArray: string[] = ["a", "b", "c"]
console.log("strArray: ", strArray)
let numArray: Array<number> = [1, 2, 3]
console.log("numArray: ", numArray)

// 元组 元组是具有固定数量和顺序的元素的数组。每个元素可以具有不同的类型
let person: [string, number] = ["John", 25]
console.log("person: ", person)


// 枚举 枚举用于定义命名的数字常量。它使代码更具可读性 枚举类型可以正向引用，反向引用
enum Color {
  Red,
  Green,
  Blue
}
// let myColor: Color = Color.Red这行代码声明了一个名为myColor的变量，它的类型被指定为前面定义的Color枚举类型，然后将Color枚举中的Red成员赋值给它
let myColor: Color = Color.Red
console.log("myColor: ", myColor)
let myColor2: string = Color[Color.Red]
console.log("myColor2: ", myColor2)

// any 表示任何类型。它允许在编译时不进行类型检查 适用于与TypeScript集成的现有JavaScript代码
let variable: any = "This can be any type."
console.log("variable: ", variable)

// unknow 未知 更加安全，在TypeScript中，unknown 类型是一个特殊的类型，表示可以是任何类型。
// 当你不知道一个变量的具体类型，或者想要确保一个变量在编译时不能是任何特定的类型时，你可以使用 unknown 类型。
let unknow: unknown = 222
unknow = true
unknow = "hello"
console.log("unknow: ", unknow)
let x = unknow
console.log("x: ", x)

/* 
// 错误写法
console.log('unknow: ', unknow.length)  
*/

// 如果需要调用属性和方法，那么你可能需要类型断言
console.log("unknow.length1: ", (unknow as string).length)
// 或者使用类型保护
if (typeof unknow === "string") {
  console.log("unknow.length2: ", unknow.length)
}

/* 
ts中any与unknown的区别:
any 类型用于表示任意类型的值，但会降低类型安全性。
unknown 类型用于表示不确定类型的值，但要求在使用前进行类型检查，以提高类型安全性。
在实际项目中，当你不确定一个变量的类型时，应优先使用 unknown 类型而不是 any 类型，以确保代码的类型安全性。
任何类型的值可以赋值给any，同时any类型的值也可以赋值给任何类型。unknown 任何类型的值都可以赋值给它，但它只能赋值给unknown和any
*/


// 类型断言
const aEle = document.querySelector("a") as HTMLAnchorElement // HTMLAnchorElement | null
const aEle2 = <HTMLAnchorElement>document.querySelector("a")
console.log(aEle,aEle2);
// 非空断言
let user: string | null | undefined = "xiaoming"
console.log(user!.toUpperCase()) // 编译正确
// console.log(user.toUpperCase()) // 错误


// 联合类型
let numberOrString: number | string = "name"
console.log(numberOrString);

function foo(params: number | string) {
  if (typeof params === "number") {
    return params
  }

  if (typeof params === "string") {
    return params.length
  }
}
console.log(foo('521'));


// void 表示函数没有返回值。通常用于指定函数没有明确的返回值
function message(message: string): void {
  console.log(message)
}
message("Hello, world!")

// never 表示永远不会发生的值的类型。通常用于表示抛出异常或无法执行到终点的函数
//  function throwError(message: string): never {
//    throw new Error(message)
//  }
//  throwError("报错了!")
</script>

<template>
</template>